package cc.loach.homekit.app.homekit;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

import cc.loach.homekit.hap.framewok.HapSettings;
import cc.loach.homekit.hap.framewok.host.HapAccessoryHostFactory;
import cc.loach.homekit.hap.framewok.manager.HapAccessoryManager;
import cc.loach.homekit.hap.framewok.store.HapKeyStoreFactory;
import cc.loach.homekit.hap.server.vertx.HapServer;
import cc.loach.homekit.hap.typedef.accessory.HapAccessory;
import cc.loach.homekit.hap.typedef.accessory.operation.HapCharacteristicOperation;
import cc.loach.homekit.hap.typedef.host.HapAccessoryHost;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;

/**
 * HomeKit服务，开发者自己可以改写
 */
public class HomeKit {

    private static final String TAG = HomeKit.class.getSimpleName();
    private static final Logger logger = LoggerFactory.getLogger(TAG);
    private final HapAccessoryManager manager;
    private final HapServer server;
    private final HapAccessoryHost host;
    private final List<HapAccessory> devices;
    private boolean started = false;

    public HomeKit(Vertx vertx, HapSettings settings, List<HapAccessory> devices) {
        // 准备设备列表
        this.devices = devices;

        // 1. 创建HomeKit设备管理器
        manager = HapAccessoryManager.create(this::onCharacteristicChanged);

        // 2. 创建HomeKit设备主机
        host = HapAccessoryHostFactory.create(vertx, this::getDevices, manager, settings);

        // 3. 创建Hap服务
        HttpServerOptions options = new HttpServerOptions();
        options.setIdleTimeout(30);
        options.setIdleTimeoutUnit(TimeUnit.SECONDS);
        options.setPort(0);
        options.setSsl(false);
        server = HapServer.create(vertx, options, host, HapKeyStoreFactory.create(settings.database()));
    }

    // 4. 提供设备列表
    private Collection<HapAccessory> getDevices() {
        return devices;
    }

    // 5. 设备属性变化时，自动发送设备属性变化通知。
    private void onCharacteristicChanged(HapCharacteristicOperation operation) {
        server.sendEvent(operation);
    }

    /**
     * 5. 启动HomeKit服务
     */
    public Future<Void> start() {
        logger.info("start");

        if (started) {
            return Future.failedFuture("already started");
        } else {
            started = true;
            return server.listen()
                    .compose(x -> host.start(x.actualPort()));
        }
    }

    /**
     * 6. 停止HomeKit服务
     */
    public Future<Void> stop() {
        logger.info("stop");

        if (started) {
            started = false;
            return host.stop()
                    .compose(x -> server.close());
        } else {
            return Future.failedFuture("already stopped");
        }
    }

    /**
     * 7. 添加HomeKit设备，accessory的did不能为空
     */
    public void add(HapAccessory accessory) {
        manager.put(accessory);
    }

    /**
     * 8. 删除HomeKit设备
     */
    public void remove(String did) {
        manager.remove(did);
    }
}
